package com.incross.dawin.views;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.http.HttpResponse;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.incross.dawin.DawinConfig;
import com.incross.dawin.http.BKConnectionManager;
import com.incross.dawin.http.parser.AdditionalInfoParser.SnsShare;
import com.incross.dawin.http.parser.AdditionalInfoParser.TickerAd;
import com.incross.dawin.http.parser.BKAdInfoParser;
import com.incross.dawin.http.parser.IconInfoParser;
import com.incross.dawin.objects.AdInfos;
import com.incross.dawin.util.BKErrorHandler;
import com.incross.dawin.util.BKImageDownloader;
import com.incross.dawin.util.BKImageDownloader.OnBitmapDownloadFinishListener;
import com.incross.dawin.util.BKLog;
import com.incross.dawin.util.CommonUtils;
import com.incross.dawin.util.CommonUtils.ScreenSize;
import com.incross.dawin.util.TickerAdBuilder;
import com.incross.dawin.util.TickerAdBuilder.Ticker;
import com.incross.dawin.util.TickerAdBuilder.TickerInfo;
import com.incross.dawin.views.BKDialog.OnDialogStateListener;

public class DawinAdPlayer extends LinearLayout implements BKConnectionManager.RequestStateListener, BKDialog.OnDialogStateListener,
SurfaceHolder.Callback, MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnVideoSizeChangedListener,
MediaPlayer.OnErrorListener {
	private static final int MESSAGE_VIDEO_START = 10000;
	
	private static final int REQUEST_START = 1000;
	private static final int REQUEST_QUARTER = 1100;
	private static final int REQUEST_QUEARTER2 = 1200;
	private static final int REQUEST_QUEARTER3 = 1300;
	private static final int REQUEST_FINISHED = 1400;
	private static final int REQUEST_SKIP = 1500;
	private static final int REQUEST_ERROR = 1600;
	private static final int REQUEST_AD_INFOS = 1700;
	private static final int REQUEST_CHARGE = 1900;
	private static final int REQUEST_PHONE_CLICK = 2000;
	private static final int REQUEST_SEND_TAG = 2100;
	
	public static final int ICON_CLICK_STOP = 123;
	public static final int ICON_CLICK_PAUSE = 456;
	
	public static final int BROWSER_MODE_INTERNEL = 10000;
	public static final int BROWSER_MODE_WEBVIEW = 20000;
	public static final int WEBVIEW_FULL = 21000;
	public static final int WEBVIEW_DIALOG = 22000;
	
	public static final int AD_FINISH_ACTION_COMPLETE = 30000;
	public static final int AD_FINISH_ACTION_SKIP = 31000;
	public static final int AD_FINISH_SCREEN_CLICK = 32000;
	public static final int AD_FINISH_ACTION_BUTTON_CLICK = 33000;
	public static final int AD_FINISH_CALL_ACTION = 34000;
	public static final int AD_FINISH_NO_APPLICABLE_AD = 35000;
	public static final int AD_FINISH_BACK_KEY_PRESSED = 35100;
	public static final int AD_FINISH_AFTER_ACTION = 35200;
	public static final int AD_FINISH_BY_SNS_SHARE = 35250;
	public static final int AD_FINISH_AFTER_SNS_SHARE = 35310;
	public static final int AD_FINISH_BY_TICKER = 35400;
	public static final int AD_FINISH_AFTER_TICKER = 35450;
	public static final int AD_FINISH_OTHER_REASON = 35300;
	
	public static final int AD_FINISH_NETWORK_DISCONNECTED = 36000;
	public static final int AD_FINISH_AD_INFO_RECEIVE_FAIL = 36100;
	public static final int AD_FINISH_OTHER_ERROR = 36200;
	
	private static final int MESSAGE_SHOW_SKIP = 100;
	private static final int MESSAGE_SHOW_PROGRESS = 101;
	private static final int MESSAGE_HIDE_PROGRESS = 102;
	private static final int MESSAGE_SHOW_ACTION_LAYOUT = 103;
	private static final int MESSAGE_ADJUST_SURFACEVIEW = 104;
	private static final int MESSAGE_ADD_SNS_SHARE = 105;
	private static final int MESSAGE_HANDLE_TICKER = 106;
	private static final int MESSAGE_REMOVE_TICKER = 107;
	private static final int MESSAGE_ADD_TICKER_VIEW = 108;
	
	private static final int CALL_STATE_IDLE = 40000;
	private static final int CALL_STATE_INCOMING = 41000;
	private static final int CALL_STATE_OUTGOING = 42000;
	
	// 송출기 응답없을시 로그 수집 url
	private static final String ADINFO_ERROR_LOG_REL = "http://adm.dawin.tv/common/dawinErrorLog.do?eCd=08010309&eUrl=";
	private static final String ADINFO_ERROR_LOG_DEV = "http://112.169.59.42:9090/common/dawinErrorLog.do?eCd=08010309&eUrl=";
	
	private int mCurrentOrientation;
	
	private int mDawinServerType = DawinConfig.DAWIN_SERVER_TEST;
	
	private final int MAX_RETRY_COUNT = 2;
	private final String AD_INFO_URL = "http://ads.dawin.tv/imp";//"http://112.169.59.43/imp";
	private final String AD_INFO_TEST_URL = "http://112.169.59.43/imp";
	
	private JSONObject mAdInfoParameter;
	
	private Context mContext;
	private Activity mActivity;
	private AttributeSet mAttributeSet;
	private int mDefStyle;
	
	private int mAdDuration;
	
	private int mDialogMarginRate = 5;
	
	private RelativeLayout mVideoLayout;
//	private SurfaceView mSurfaceView;
	private SurfaceHolder mSurfaceHolder;
	private MediaPlayer mMediaPlayer;
	
	private ImageButton mFacebookButton, mTwitterButton, mSkipButton, mSkipDescriptionButton;
	private ImageButton mCallButton, mMapButton, mEventButton, mDownloadButton;
	
	private LinearLayout mSnsLayout, mEventLayout, mCallLayout, mDownloadLayout, mMapLayout, mSkipLayout, mShareLayout;
	
	// Add views for snsShare
	private LinearLayout mSnsShareContentLayout;
	private RelativeLayout mSnsBottomLayout;
	private ImageButton mSnsShareButton;
	private boolean mIsSnsEtcButtonClicked = false;
	
	private OnPlayFinishListener mPlayFinishListener;
	private OnErrorListener mErrorListener;
	private OnPreparedListener mPreparedListener;
	private OnTimeListener mTimeListener, mTickerTimeListener;
	private OnVideoInfoReceiveListener mVideoInfoListener;
	
	private BKConnectionManager mConnectionManager;
	
	private ProgressBar mProgress;
	
	private AdInfos mAdInfos;
	private BKImageDownloader mImageDownloader;
	private int mQuarter, mQuarter2, mQuarter3;
	private int mCurrentQuarter = 1;
	private int mLastSendedTag = 0;
	private MediaController mMediaController;
	private boolean mIsStartTagSended = false;
	
	private boolean mIsVideoClickProcessing = false;
	
	private boolean mIsDawinPlaying = false;
	
	// flags for call(incoming outgoing)
	private int mCurrentCallState = CALL_STATE_IDLE;
	
	// 20141230 현재 전화가능상태를 체크하기 위한 변수
	private int mCurrentServiceState = ServiceState.STATE_OUT_OF_SERVICE;
	
	
	private int mButtonSize = 60;
	private int mSkipButtonWidth = 150;
	private int mSkipDescWidth = 468;
	private int mSkipButtonHeight = 156;
	
	// 20140922 Action button size changed. xhdpi 기준 사이즈
	private int mActionButtonWidth = 80;
	private int mActionButtonHeight = 80;
	
	private boolean mIsClickviewerShown = false;
	private boolean mIsOnPauseCalled = false;
	private boolean mIsSnsShareClicked = false;
	private boolean mIsTickerClicked = false;
	
	
	private int mAdInfoRetryCount = 0;
	private int mChargeTagRetryCount = 0;
	
	private boolean mIsChargeTagSendSucceed = false;
	private boolean mIsChargeTagSended = false;
	
	private int mDeviceDensity;
	
	private BKErrorHandler mErrorHandler;
	
	private int mChargeTime = 0;
	
	private String xmlString;
	
	// 광고 요청 url 저장 : 광고정보 수신 실패시 서버에 보내는 용도.
	private String mAdinfoRequestUrl = "";
	
	private Timer mTimer;
	private TimerTask mTimerTask;
	private boolean mIsTimerRunning = false;
	
	private Timer mTickerTimer;
	private TimerTask mTickerTimerTask;
	private boolean mIsTickerTimerRunning = false;
	
	// player 초기화 여부 구분용 flag
	private boolean mIsPlayerInitialized = false;
	
	// 타이머 내부 동작 구분용 flag
	private boolean mIsVideoPlaying = false;
	
	// 비디오 비율 담은 변수
	private int mWidthRatio = -1, mHeightRatio = -1;
	
	// prepared video size
	private int mVideoWidth = -1, mVideoHeight = -1;
	
	// 주어진 화면에 맞도록 surfaceholder에 사용할 고정값 저장
	private int mPortFixedWidth = -1, mPortFixedHeight = -1;
	private int mLandFixedWidth = -1, mLandFixedHeight = -1;
	
	private int mPortParentWidth = -1, mPortParentHeight = -1;
	private int mLandParentWidth = -1, mLandParentHeight = -1;
	
	
	// 15초 광고인 경우 과금태그를 광고가 끝나는 시점에 호출하기 위해 체크
	private boolean mIsQuarterMinAd = false;
	
	// T store 설치여부 저장하는 flag
	private boolean mIsTstoreInstalled = false;
	
	// kakao talk, kakao story 설치여부 저장하는 flag
	private boolean mIsKakaoTalkInstalled = false;
	private boolean mIsKakaoStoryInstalled = false;
	
	// 20141222 sns Share처럼 버튼을 무더기로 넣는 경우 참고 변수(공통 라이브러리 20141216수정본)
	private boolean mIsButtonClickable = false;
	
	// ticker 관련 변수
	private Ticker mTicker = null;
	private boolean mIsTickerShowing = false;
	private int mCurrentTickerNum = 0;
	private int mCurrentShowingTickerOrientation = -1;
	
	private ImageButton mTickerButton;
	
	
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch(msg.what) {
				case MESSAGE_SHOW_SKIP:
					if(mSkipButton != null) {
						mSkipDescriptionButton.setVisibility(View.GONE);
						mSkipButton.setVisibility(View.VISIBLE);
					}
					break;
					
				case MESSAGE_SHOW_PROGRESS:
					showProgress();
					break;
					
				case MESSAGE_HIDE_PROGRESS:
					hideProgress();
					break;
					
				case MESSAGE_SHOW_ACTION_LAYOUT:
					showActionLayout();
					
					if(mAdInfos.isAvailable(AdInfos.SKIP) || mAdInfos.isAvailable(AdInfos.SKIP_DESCRIPTION)) {
						mSkipLayout.setVisibility(View.VISIBLE);
					} else {
						mSkipLayout.setVisibility(View.GONE);
					}
					break;
					
				case MESSAGE_ADJUST_SURFACEVIEW:
					setSurfaceViewSize();
					break;
					
				case MESSAGE_ADD_SNS_SHARE:
					if(mAdInfos.isSnsShareAvailable()) {
						addSnsShareView(mAdInfos.getSnsShareList());
					}
					break;
					
				case MESSAGE_HANDLE_TICKER:
					if(mIsDawinPlaying) {
						handleTickerView();
					}
					
					break;
					
				case MESSAGE_REMOVE_TICKER:
					removeTickerView();
					break;
					
				case MESSAGE_ADD_TICKER_VIEW:
					addTickerView(mAdInfos.getTickerList());
					break;
			}
		}
	};
	
	private void initTelephonyManager() {
		TelephonyManager tManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 
		tManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
		tManager.listen(new PhoneStateListener() {
			@Override
			public void onServiceStateChanged(ServiceState serviceState) {
				switch (serviceState.getState()) {
		        case ServiceState.STATE_POWER_OFF:
		        	BKLog.w("Call service state : State power off");
		        	mCurrentServiceState = ServiceState.STATE_POWER_OFF;
		            break;
		        case ServiceState.STATE_IN_SERVICE:
		        	BKLog.w("Call service state : State in service");
		        	mCurrentServiceState = ServiceState.STATE_IN_SERVICE;
		            break;
		        case ServiceState.STATE_OUT_OF_SERVICE:
		        	BKLog.w("Call service state : State out of service");
		        	mCurrentServiceState = ServiceState.STATE_OUT_OF_SERVICE;
		            break;
		        case ServiceState.STATE_EMERGENCY_ONLY:
		        	BKLog.w("Call service state : State emergency only");
		        	mCurrentServiceState = ServiceState.STATE_EMERGENCY_ONLY;
		            break;
		        default:
		        	BKLog.w("Call service state : default value(out of service)");
		        	mCurrentServiceState = ServiceState.STATE_OUT_OF_SERVICE;
		            break;
		        }
			}
		}, PhoneStateListener.LISTEN_SERVICE_STATE);
	}
	
	// 20141230 폰스테이트 리스너 이외에 현재 상태 체크하는 리스너 추가.
	
	private PhoneStateListener phoneStateListener = new PhoneStateListener() {
		public void onCallStateChanged(int state, String incomingNumber) {// 전화 수신 반응.
			 // 착신 전화 번호를 받는다.
			 switch (state) {
				 case TelephonyManager.CALL_STATE_IDLE :  
					 break; // 폰이 울리거나 통화중이 아님.o
				 case TelephonyManager.CALL_STATE_RINGING :
					 mCurrentCallState = CALL_STATE_INCOMING;
					 
					 if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
						 mMediaPlayer.pause();
					 }
					 if(mPlayFinishListener != null) {
						 mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_CALL_ACTION);
						 mIsClickviewerShown = true;
					 }
					 destroy();
					 
					 break; // 폰이 울린다.
				 case TelephonyManager.CALL_STATE_OFFHOOK :
					 break; // 폰이 현재 통화 중.
				 default:      
					 break;
			 }
		 }
	};
	
	public interface OnAdViewStateListener {
		public abstract void onPrepared(MediaPlayer mp);
		public abstract void onHttpRequestError();
	}
	
	
	public interface OnPlayFinishListener {
		public abstract void onPlayFinished(DawinAdPlayer dawinPlayer, int finishedBy);
	}
	
	public interface OnPreparedListener {
		public abstract void onPrepared();
	}
	
	public interface OnTimeListener {
		public abstract void OnTime(int currMsec);
	}
	
	public interface OnVideoInfoReceiveListener {
		public abstract void onVideoInfoReceived(int videoWidth, int videoHeight, int duration);
	}
	
	/**
	 * same as MediaPlayer.OnErrorListener
	 */
	public interface OnErrorListener {
		public abstract void onError(MediaPlayer mp, int what, int extra);
	}
	
	public DawinAdPlayer(Activity activity) {
		super(activity);
		mActivity = activity;
		mContext = activity.getApplicationContext();
		init();
		initializeVideoView();
	}
	
	/*public DawinAdPlayer(Activity activity, SurfaceView surfaceView) {
		super(activity);
		mActivity = activity;
		mContext = activity.getApplicationContext();
		mSurfaceView = surfaceView;
		mSurfaceHolder = mSurfaceView.getHolder();
		mSurfaceHolder.addCallback(this);
		init();
		initializeVideoView();
	}*/
	
	public DawinAdPlayer(Activity activity, SurfaceHolder surfaceHolder) {
		super(activity);
		mActivity = activity;
		mContext = activity.getApplicationContext();
		mSurfaceHolder = surfaceHolder;
		mSurfaceHolder.addCallback(this);
		mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		LinearLayout.LayoutParams playerParam = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT, 1.0f);
		setLayoutParams(playerParam);
		
		init();
		initializeVideoView();
	}
	
	public void setDawinServerType(int type) {
		if(type != DawinConfig.DAWIN_SERVER_REAL && type != DawinConfig.DAWIN_SERVER_TEST) return;
		mDawinServerType = type;
	}
	
	private void init() {
		mIsTstoreInstalled = CommonUtils.isPackageInstalled(mContext, "com.skt.skaf.A000Z00040");
		mIsKakaoTalkInstalled = CommonUtils.isPackageInstalled(mContext, "com.kakao.talk");
		mIsKakaoStoryInstalled = CommonUtils.isPackageInstalled(mContext, "com.kakao.story");
		
		initTelephonyManager();
		
		mConnectionManager = new BKConnectionManager(mContext);
		mImageDownloader = new BKImageDownloader(mContext);
		mConnectionManager.setOnConnectionStateListener(this);
		CommonUtils.getDeviceType(mContext);
		mErrorHandler = new BKErrorHandler(mContext);
		
		mDeviceDensity = CommonUtils.getDensity(mContext);
		
		if(mDeviceDensity == CommonUtils.DENSITY_LDPI) { // ldpi
			BKLog.i("-- LDPI");
			// 20141007 mdpi 기준 85% 
			mButtonSize = 40;
			mSkipButtonWidth = 55;
			mSkipButtonHeight = 51;
			mSkipDescWidth = 155;
			// 20141007 mdpi 기준  사이즈의 85%.
			mActionButtonWidth = 60;
			mActionButtonHeight = 60;
		} else if(mDeviceDensity == CommonUtils.DENSITY_MDPI) { // mdpi
			BKLog.i("-- MDPI");
			// 20141007 hdpi 기준 85% 
			mButtonSize = 47;
			mSkipButtonWidth = 65;
			mSkipButtonHeight = 60;
			mSkipDescWidth = 182;
			// 20141007 hdpi 기준 사이즈의 85%.
			mActionButtonWidth = 71;
			mActionButtonHeight = 71;
		} else if(mDeviceDensity == CommonUtils.DENSITY_HDPI) { // hdpi
			BKLog.i("-- HDPI");
			// 20141007 xhdpi 기준 70% 
			mButtonSize = 55;
			mSkipButtonWidth = 76;
			mSkipButtonHeight = 71;
			mSkipDescWidth = 214;
			// 20141007 xhdpi 기준 사이즈의 70%.
			mActionButtonWidth = 83;
			mActionButtonHeight = 83;
		} else if(mDeviceDensity == CommonUtils.DENSITY_XHDPI) { // xhdpi ##################### 기준 사이즈 #######################
			BKLog.i("-- XHDPI");
			// 20141007 xhdpi를 기준으로 함.
			mButtonSize = 79;
			mSkipButtonWidth = 108;
			mSkipButtonHeight = 102;
			mSkipDescWidth = 305;
			// 20141007 xhdpi 기준이고 실제 버튼 사이즈로 설정함.
			mActionButtonWidth = 119;
			mActionButtonHeight = 119;
		} else if(mDeviceDensity == CommonUtils.DENSITY_XXHDPI) { // xxdpi
			// 25% higher than xhdpi
			mButtonSize = 99;
			mSkipButtonWidth = 135;
			mSkipButtonHeight = 128;
			mSkipDescWidth = 381;
			// 20141007 xhdpi 기준 125%
			mActionButtonWidth = 149;
			mActionButtonHeight = 149;
		} else if(mDeviceDensity == CommonUtils.DENSITY_SXHDPI) { // sxhdpi
			// 20% higher than xxhdpi
			mButtonSize = 119;
			mSkipButtonWidth = 162;
			mSkipButtonHeight = 154;
			mSkipDescWidth = 457;
			// 20141007 xxhdpi 기준 120%
			mActionButtonWidth = 179;
			mActionButtonHeight = 179;
		}
		
		if(mTimeListener == null) {
			mTimeListener = new OnTimeListener() {
				@Override
				public void OnTime(int currMsec) {
					// 비디오 실제 시작여부 판단
					if(currMsec > 10 && !mIsVideoPlaying) {
						videoStarted();
						mIsDawinPlaying = true;
						if(mAdInfos.isTickerAvailable()) {
							mHandler.sendEmptyMessage(MESSAGE_ADD_TICKER_VIEW);
							startTickerTimer();
						}
						
						if(mAdInfos.isSnsShareAvailable()) {
							mHandler.sendEmptyMessage(MESSAGE_ADD_SNS_SHARE);
						}
					}
					
					// Skip button show
					if(mAdInfos != null && !mSkipButton.isShown()) {
						if(currMsec > mAdInfos.getIconShowTime(AdInfos.SKIP)) {
							mHandler.sendEmptyMessage(MESSAGE_SHOW_SKIP);
						}
					}
					
					// charge time?
					if(mAdInfos != null && !mIsQuarterMinAd && !mIsChargeTagSended) {
						if(currMsec > mChargeTime) {
							mIsChargeTagSended = true;
							mConnectionManager.sendRequest(REQUEST_CHARGE, mAdInfos.getChargeTag(), null);
						}
					}
					
					// quarter check
					if(mAdInfos != null && mLastSendedTag != 3) {
						if(currMsec > mQuarter && currMsec < mQuarter2) {
							if(mCurrentQuarter != 2) {
								mCurrentQuarter = 2;
								BKLog.d("Quarter2!");
								mConnectionManager.sendRequest(REQUEST_QUARTER, mAdInfos.getQuarterTag(1), null);
								mLastSendedTag = 1;
							}
						} else if(currMsec > mQuarter2 && currMsec < mQuarter3) {
							if(mCurrentQuarter != 3) {
								mCurrentQuarter = 3;
								BKLog.d("Quarter3!");
								mConnectionManager.sendRequest(REQUEST_QUEARTER2, mAdInfos.getQuarterTag(2), null);
								mLastSendedTag = 2;
							}
						} else if(currMsec > mQuarter3) {
							if(mCurrentQuarter != 4) {
								mCurrentQuarter = 4;
								BKLog.d("Quarter4!");
								mConnectionManager.sendRequest(REQUEST_QUEARTER3, mAdInfos.getQuarterTag(3), null);
								mLastSendedTag = 3;
							}
						}
					}
					
					if(currMsec > mAdDuration - 1000) {
						lockClickEvents(false);
					}
					
				}
			};
			
			if(mTickerTimeListener == null) {
				mTickerTimeListener = new OnTimeListener() {
					@Override
					public void OnTime(int currMsec) {
						
						// 티커관련 처리.. 
						if(mTicker != null && mAdInfos != null) {
							int duration = Integer.parseInt(mAdInfos.getAdDuration());
							if(currMsec > 0 && currMsec <= duration) {
								BKLog.e("--------------------- onTime(" + currMsec + ")");
								int maxCount = mTicker.getTickerList().size();
								if(mCurrentTickerNum < maxCount) {
									TickerInfo info = mTicker.getTickerList().get(mCurrentTickerNum);
									
									if(mIsTickerShowing) {
										// 티커가 보여지는 상태에서 이곳에 들어오는 경우는 종료시간 체크하는 것으로 간주함.
										if(currMsec >= info.getEndViewTime()) {
											mHandler.sendEmptyMessage(MESSAGE_REMOVE_TICKER);
										}
									} else {
										// 현재 해당된 티커가 나와야 되는 시간이 맞는 경우, 티커를 보여주도록 한다.
										if(currMsec >= info.getStartViewTime() && currMsec <= info.getEndViewTime()) {
											mHandler.sendEmptyMessage(MESSAGE_HANDLE_TICKER);
										}
									}
								}
							}
						}
					}
				};
			}
		}
	}
	
	public RelativeLayout.LayoutParams changePositionByNumber(RelativeLayout.LayoutParams param, int position) {
		RelativeLayout.LayoutParams result = new RelativeLayout.LayoutParams(param.width, param.height);
		if(position > 0 && position < 8) {
			switch(position) {
				case 1: // left top
					result.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
					result.addRule(RelativeLayout.ALIGN_PARENT_TOP);
					break;
					
				case 2: // left center
					result.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
					result.addRule(RelativeLayout.CENTER_VERTICAL);
					break;
					
				case 3: // left bottom
					result.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
					result.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
					break;
					
				case 4: // center top
					result.addRule(RelativeLayout.CENTER_HORIZONTAL);
					result.addRule(RelativeLayout.ALIGN_PARENT_TOP);
					break;
					
				case 5: // center bottom
					result.addRule(RelativeLayout.CENTER_HORIZONTAL);
					result.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
					break;
					
				case 6: // right top
					result.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
					result.addRule(RelativeLayout.ALIGN_PARENT_TOP);
					break;
					
				case 7: // right center
					result.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
					result.addRule(RelativeLayout.CENTER_VERTICAL);
					break;
			}
		} else return param;
		
		
		return result;
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
	}
	
	@Override
	protected void onSizeChanged (int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		BKLog.d("====================on size changed=============================");
		BKLog.d("w : " + w + ", h : " + h + ", oldw : " + oldw + ", oldh : " + oldh);
		
		if(oldw != w) {
			if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
				mCurrentOrientation = Configuration.ORIENTATION_PORTRAIT;
				BKLog.e("portrait");
				if(mPortParentWidth == -1 && mPortParentHeight == -1) {
					mPortParentWidth = w;
					mPortParentHeight = w;
				}
				setFixedVideoSize(Configuration.ORIENTATION_PORTRAIT);
				if(mPortFixedWidth != 0 && mPortFixedHeight != 0) {
					mHandler.sendEmptyMessage(MESSAGE_ADJUST_SURFACEVIEW);
				}
			} else {
				mCurrentOrientation = Configuration.ORIENTATION_LANDSCAPE;
				BKLog.e("landscape");
				if(mLandParentWidth == -1 && mLandParentHeight == -1) {
					mLandParentWidth = w;
					mLandParentHeight = h;
				}
				setFixedVideoSize(Configuration.ORIENTATION_LANDSCAPE);
				if(mLandFixedWidth != -1 && mLandFixedHeight != -1) {
					mHandler.sendEmptyMessage(MESSAGE_ADJUST_SURFACEVIEW);
				}
			}
			
			// 20141128 기존에 다윈이 play중이 아니면 사이즈 셋팅이 안되도록 설정이 되어 다윈 영상 재생직전에 화면을 돌린경우 가로 사이즈 측정이 안되는 문제점이 있었다. 다윈 플레이 여부가 아닌, 티커가 있을때 설정하는 것으로 변경적용.
			if(mTicker != null && mAdInfos.isTickerAvailable()) {
				mTicker.setScreenSize(mCurrentOrientation, new ScreenSize(w, h));
			}
			
			if(mIsTickerShowing) {
				Message msg = new Message();
				msg.what = MESSAGE_HANDLE_TICKER;
				mHandler.sendMessageDelayed(msg, 100);
			}
		} else {
			BKLog.e("Wrong case!!! old width can not same as current width.");
		}
	}
	
	private void setFixedVideoSize(int orientation) {
		if(mWidthRatio != 0 && mHeightRatio != 0) {
			if(orientation == Configuration.ORIENTATION_LANDSCAPE) {
				if(mLandFixedWidth == -1 || mLandFixedHeight == -1) {
					ScreenSize size = getOptimalVideoSize(mLandParentWidth, mLandParentHeight, mWidthRatio, mHeightRatio);
					mLandFixedWidth = size.getWidth();
					mLandFixedHeight = size.getHeight();
					BKLog.i("##########################################################################");
					BKLog.i("LandFixed size set!!(w" + mLandFixedWidth + ",h" + mLandFixedHeight + ")");
					BKLog.i("##########################################################################");
				}
			} else {
				if(mPortFixedWidth == -1 || mPortFixedHeight == -1) {
					ScreenSize size = getOptimalVideoSize(mPortParentWidth, mPortParentHeight, mWidthRatio, mHeightRatio);
					mPortFixedWidth = size.getWidth();
					mPortFixedHeight = size.getHeight();
					BKLog.i("##########################################################################");
					BKLog.i("PortFixed size set!!(w" + mPortFixedWidth + ",h" + mPortFixedHeight + ")");
					BKLog.i("##########################################################################");
				}
			}
		}
		
	}
	
	@Override
	protected void onDraw (Canvas canvas) {
		super.onDraw(canvas);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
	}
	
	
	/**
	 * must call onResume at activity's onResume();
	 */
	public void onResume() {
		// finish Activity when call event
		BKLog.e("onResume dawinadplayer");
		/*if(mCurrentCallState == CALL_STATE_INCOMING || mCurrentCallState == CALL_STATE_OUTGOING) {
			BKLog.w("Call finish");
			if(mPlayFinishListener != null) {
				 mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_CALL_ACTION);
			}
		} else */
		if(mIsSnsShareClicked){
			initializeVideoView();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_SNS_SHARE);
			}
		} else if(mIsTickerClicked) {
			initializeVideoView();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_TICKER);
			}
		} else if(mIsClickviewerShown) {
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_ACTION);
			}
		} else if(mIsOnPauseCalled) {
			BKLog.e("isPauseCalled!!");
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
			}
		}
	}
	
	private void setViews() {
		BKLog.e("SetViews");
		// ##Ben afreeca test
		/*if(mSurfaceView == null) {
			return;
		}*/
		if(mSurfaceHolder == null) {
			return;
		}
		
		LinearLayout.LayoutParams mainParam = 
				new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
		
		mainParam.setMargins(0, 0, 0, 0);
		
		mVideoLayout = new RelativeLayout(mContext);
		mVideoLayout.setBackgroundColor(Color.parseColor("#00000000"));
		
		RelativeLayout.LayoutParams buttonLayoutParam = 
				new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		buttonLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		buttonLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		
		
		// ##Ben test for afreeca
		// block screen touch.
		mVideoLayout.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null && !mIsVideoClickProcessing) {
					if(mAdInfos.getVideoClickTracking() != null && !mAdInfos.getVideoClickTracking().equals("")) {
						BKLog.e("onClick.. ------>>> VideoLayout");
						mIsVideoClickProcessing = true;
						lockClickEvents(false);
						cancelTimer();
						if(mMediaPlayer.isPlaying()) {
							mMediaPlayer.pause();
						}
						showProgress();
						handleScreenClick(mAdInfos.getVideoClickTracking() + getActionButtonParameter(), mAdInfos.getVideoclickThrough());
					}
				}
			}
		});
//		mVideoLayout.setOnTouchListener(new OnTouchListener() {
//			
//			@Override
//			public boolean onTouch(View v, MotionEvent event) {
//				if(mAdInfos != null && !mIsVideoClickProcessing) {
//					if(mAdInfos.getVideoClickTracking() != null && !mAdInfos.getVideoClickTracking().equals("")) {
////						BKLog.e("ontouch");
//						mIsVideoClickProcessing = true;
//						lockClickEvents(false);
//						cancelTimer();
//						if(mMediaPlayer.isPlaying()) {
//							mMediaPlayer.pause();
//						}
//						showProgress();
//						handleScreenClick(mAdInfos.getVideoClickTracking() + getActionButtonParameter(), mAdInfos.getVideoclickThrough());
//					}
//				}
//				
//				return false;
//			}
//		});
		
		
		mSnsLayout = new LinearLayout(mContext);
		mSnsLayout.setOrientation(LinearLayout.HORIZONTAL);
		mSnsLayout.setVisibility(View.GONE);
		
		mEventLayout = new LinearLayout(mContext);
		mEventLayout.setVisibility(View.GONE);
		
		mCallLayout = new LinearLayout(mContext);
		mCallLayout.setVisibility(View.GONE);
		
		mDownloadLayout = new LinearLayout(mContext);
		mDownloadLayout.setVisibility(View.GONE);
		
		mMapLayout = new LinearLayout(mContext);
		mMapLayout.setVisibility(View.GONE);
		
		mSkipLayout = new LinearLayout(mContext);
		mSkipLayout.setVisibility(View.GONE);
		
		RelativeLayout.LayoutParams buttonParams = 
				new RelativeLayout.LayoutParams(mActionButtonWidth, mActionButtonHeight);
		buttonParams.setMargins(6, 0, 0, 0);
		
		RelativeLayout.LayoutParams skipLayoutParam = 
			new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		skipLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		skipLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		
//		mVideoLayout.addView(mSurfaceView, mSurfaceParam);
		mVideoLayout.addView(mSnsLayout, buttonLayoutParam);
		mVideoLayout.addView(mEventLayout, buttonLayoutParam);
		mVideoLayout.addView(mCallLayout, buttonLayoutParam);
		mVideoLayout.addView(mDownloadLayout, buttonLayoutParam);
		mVideoLayout.addView(mMapLayout, buttonLayoutParam);
		mVideoLayout.addView(mSkipLayout, skipLayoutParam);
		
		
		
		// 20140919 me2day 서비스 종료로 인해 Me2day관련 삭제함
		mFacebookButton = new ImageButton(mContext);
		mFacebookButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelTimer();
					if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
						mMediaPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.FACEBOOK, mAdInfos.getTrackingUrl(AdInfos.FACEBOOK) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.FACEBOOK));
				}
			}
		});
		
		mTwitterButton = new ImageButton(mContext);
		mTwitterButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelTimer();
					if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
						mMediaPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.TWITTER, mAdInfos.getTrackingUrl(AdInfos.TWITTER) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.TWITTER));
				}
			}
		});
		
		// init other buttons
		mCallButton = new ImageButton(mContext);
		mCallButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					
					lockClickEvents(false);
					cancelTimer();
					if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
						mMediaPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.CALL, mAdInfos.getClickThrough(AdInfos.CALL), null);
				}
				
			}
		});
		
		mMapButton = new ImageButton(mContext);
		mMapButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelTimer();
					if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
						mMediaPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.MAP, mAdInfos.getTrackingUrl(AdInfos.MAP) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.MAP));
				}
				
			}
		});
		
		mEventButton = new ImageButton(mContext);
		mEventButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelTimer();
					if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
						mMediaPlayer.pause();
					}
					showProgress();
					handleActionClick(AdInfos.EVENT, mAdInfos.getTrackingUrl(AdInfos.EVENT) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.EVENT));
				}
				
			}
		});
		
		mDownloadButton = new ImageButton(mContext);
		mDownloadButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelTimer();
					// 20140113 수동으로 미디어 플레이어를 릴리즈 하지 않고 모두 Destroy에 맡기는 것으로 변경함
					destroy();
					mIsClickviewerShown = true;
					
					showProgress();
					/* 20130806 예외적으로 Download Action 클릭에서만 리다이렉트 시키지 않는 것으로 서버팀과 협의함
					  기획팀의 만행으로(만들어준 테스트 앱 확인 안해봄) 기존에는 클릭뷰어에서 처리하던 것을 클릭뷰어를 
					  띄우지 않고 처리하는 것으로 변경함 */
					// 태그 전송용 url
					String appTagUrl = mAdInfos.getTrackingUrl(AdInfos.DOWNLOAD) + getActionButtonParameter();
					mConnectionManager.sendRequest(REQUEST_SEND_TAG, appTagUrl, null);
					
					// 스토어 연결에 사용할 url
					// 2013.09.30 화면클릭시에도 다운로드가 가능하도록 하기위해서 코드 중복배제를 위해 메소드로 분리
					downloadApp(mAdInfos.getClickThrough(AdInfos.DOWNLOAD).trim());
					
//					기존 클릭뷰어로 보내던 동작 주석처리
//					handleActionClick(AdInfos.DOWNLOAD, mAdInfos.getTrackingUrl(AdInfos.DOWNLOAD) + getActionButtonParameter(), mAdInfos.getClickThrough(AdInfos.DOWNLOAD));
				}
				
			}
		});
		
		
		// Add sns buttons to sns layout.
		mSnsLayout.addView(mFacebookButton, buttonParams);
		mSnsLayout.addView(mTwitterButton, buttonParams);
		
		// Add call button to call layout
		mCallLayout.addView(mCallButton, buttonParams);
		
		// Add download button to download layout
		mDownloadLayout.addView(mDownloadButton, buttonParams);
		
		// Add map button to map layout
		mMapLayout.addView(mMapButton, buttonParams);
		
		// Add event button to event layout
		mEventLayout.addView(mEventButton, buttonParams);
		
		mSkipButton = new ImageButton(mContext);
		mSkipButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					showProgress();
					if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
						mMediaPlayer.stop();
						mMediaPlayer.setDisplay(null);
					}
					cancelTimer();
					
					mConnectionManager.sendRequest(REQUEST_SKIP, mAdInfos.getSkipTag(), null);
				}
			}
		});
		
		mSkipDescriptionButton = new ImageButton(mContext);
		
		mFacebookButton.setVisibility(View.GONE);
		mTwitterButton.setVisibility(View.GONE);
		mSkipButton.setVisibility(View.GONE);
		mSkipDescriptionButton.setVisibility(View.GONE);
		mDownloadButton.setVisibility(View.GONE);
		mMapButton.setVisibility(View.GONE);
		mCallButton.setVisibility(View.GONE);
		mEventButton.setVisibility(View.GONE);
		
		
		
		LinearLayout.LayoutParams skipButtonParam = 
				new LinearLayout.LayoutParams(mSkipButtonWidth, mSkipButtonHeight);
		
		LinearLayout.LayoutParams skipDescriptionButtonParam = 
			new LinearLayout.LayoutParams(mSkipDescWidth, mSkipButtonHeight);
		
		
		mSkipLayout.addView(mSkipButton, skipButtonParam);
		mSkipLayout.addView(mSkipDescriptionButton, skipDescriptionButtonParam);
		
		// Progress bar
		mProgress = new ProgressBar(mContext, null, android.R.attr.progressBarStyle);
		mProgress.setVisibility(View.GONE);
		RelativeLayout.LayoutParams progressParam = 
				new RelativeLayout.LayoutParams(mButtonSize, mButtonSize);
		progressParam.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
		mVideoLayout.addView(mProgress, progressParam);
		
		
		
		DawinAdPlayer.this.addView(mVideoLayout, mainParam);
	}
	
	/**
	 * 2013.09.30 화면클릭으로 다운로드가 가능하도록 하기위해 변경함.
	 * 광고에서 지정한 앱 다운로드시에 사용함.
	 * @param downloadUrl : T-store 또는 Android 지원하는 형식의 주소 사용.
	 * @return
	 */
	public boolean downloadApp(String downloadUrl) {
		if(downloadUrl == null || downloadUrl.equals("")) return false;
		// 20131001 어쨋던 외부로 나간 후 종료하는 것이므로, 이 경우 클릭뷰어 종료로 처리함.(기존 다운로드가 그렇게 처리중이었음)
		mIsClickviewerShown = true;
		if(downloadUrl.contains("tstore://")) {
			BKLog.e("T store app!! : " + downloadUrl);
			String key = downloadUrl.substring(9);
			if(mIsTstoreInstalled) {
				try {
					Intent intent = new Intent();
					intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
					intent.setClassName("com.skt.skaf.A000Z00040", "com.skt.skaf.A000Z00040.A000Z00040");
					intent.setAction("COLLAB_ACTION");
					intent.putExtra("com.skt.skaf.COL.URI", key.getBytes());
					intent.putExtra("com.skt.skaf.COL.REQUESTER", "A000Z00040");
					mActivity.startActivity(intent);
				} catch(ActivityNotFoundException e) {
					// 20140113 Afreeca에서 왜인지는 모르겠으나 겔럭시 S2에서 패키지 검사를 해서 있다고 나온 티스토어가 없다고 나오는 경우를 발견함.
					// 이게 나오는 경우 로그를 찍도록 하겠음.
					e.printStackTrace();
					Log.w("Dawin", "Dawin weird information : ");
					Log.w("Dawin", "Model : " + Build.MODEL);
					Log.w("Dawin", "Android version : " + android.os.Build.VERSION.RELEASE);
					showTstoreWebPage(downloadUrl);
				}
				
			} else {
				showTstoreWebPage(downloadUrl);
			}   
			BKLog.e(key);
			
			
		} else if(downloadUrl.contains("market://")) {
			BKLog.e("google market app!!" + downloadUrl);
			Intent intent = new Intent(Intent.ACTION_VIEW);
			intent.addCategory(Intent.CATEGORY_DEFAULT);
			intent.setData(Uri.parse(downloadUrl));
			mActivity.startActivity(intent);
		} else {
			// 예외상황이라서 기타 오류로 종료 처리.
			mIsClickviewerShown = false;
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			}
			return false;
		}
		
		return true;
	}
	
	// 20140113 티스토어관련페이지 연결부분 외부로 뺌. --> 티스토어가 깔려있다고 판단한경우이지만 ActivityNotFoundException이 나오는 경우 함께 사용.
	public void showTstoreWebPage(String url) {
		/* 20130809 기획팀은 앱 설치가 되지 않은 경우 설치 안내페이지로 연결해달라는 말에 동의를 했으나 자세한 설명을 해주지 않았음에도 불구하고 이렇게 되는 것이 아니라며 또다시 내용을 수정함
		 * 현재 설치 안내페이지에서 http://tsto.re/앱정보 형식으로 외부 브라우저로 연결하도록 변경함.*/
		BKLog.e("tstore not installed. go to install guide page.");
		String[] splitString = url.split("PRODUCT_VIEW/");
		String downloadInfo = (splitString[1].split("/"))[0];
		BKLog.e("download info : " + downloadInfo);
		
		Intent i = new Intent(Intent.ACTION_VIEW);
		Uri u = Uri.parse("http://tsto.re/" + downloadInfo);
		i.setData(u); 
		mActivity.startActivity(i);
	}
	
	private void videoStarted() {
		mIsVideoPlaying = true;
		BKLog.i("onVideoStarted =============>");
		mIsDawinPlaying = true;
		try {
			if(mAdInfos != null) {
				mHandler.sendEmptyMessage(MESSAGE_HIDE_PROGRESS);
				if(!mIsStartTagSended) {
					mIsStartTagSended = true;
					mConnectionManager.sendRequest(REQUEST_START, mAdInfos.getStartTag(), null);
				}
				
				
				mHandler.sendEmptyMessage(MESSAGE_SHOW_ACTION_LAYOUT);
			}
			
		} catch(Exception e) {
			// 잘못된 상황임.
			
		}
				
	}
	
	private void startTickerTimer() {
		if(mTickerTimer != null && mTickerTimerTask != null && !mIsTickerTimerRunning) {
			mIsTickerTimerRunning = true;
			mTickerTimer.schedule(mTickerTimerTask, 0, 300);
		}
	}
	
	private void cancelTickerTimer() {
		BKLog.e("finish combined timer");
		if(mIsTickerTimerRunning) {
			mIsTickerTimerRunning = false;
			if(mTickerTimer != null) {
				mTickerTimer.cancel();
				mTickerTimer.purge();
				mTickerTimer = null;
			}
			
			if(mTickerTimerTask != null) {
				mTickerTimerTask.cancel();
				mTickerTimerTask = null;
			}
		}
	}
	
	
	private void handleActionClick(int which, String handleInfo, String pageUrl) {
		if(mPlayFinishListener != null) {
			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_BUTTON_CLICK);
		}
		// 20140113 수동으로 미디어 플레이어를 릴리즈 하지 않고 모두 Destroy에 맡기는 것으로 변경함
		destroy();
		
		if(which == AdInfos.CALL) {
			showCallDialog(handleInfo);
		} else {
			showBrowserDialog(handleInfo, (mAdInfos != null?mAdInfos.getAdTitle():""), pageUrl);
		}
	}
	
	private void handleScreenClick(String handleInfo, String pageUrl) {
		if(mAdInfos == null) return;
		
		// 20131001 화면 클릭의 경우 클릭뷰어가 뜨던 외부 브라우저로 가던 다른 액션이 일어나므로 중복되는 코드이기 때문에 주석처리함.
//		if(mPlayFinishListener != null) {
//			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_SCREEN_CLICK);
//		}
		
		// 20140113 수동으로 미디어 플레이어를 릴리즈 하지 않고 모두 Destroy에 맡기는 것으로 변경함
		destroy();
		// 20130930 전화, 다운로드 화면클릭으로도 가능하도록 수정. 기획팀과 협의내용은 2013 09 27 오후 2:33 메일 확인
		if(mAdInfos.getActionMode() == AdInfos.ACTION_MODE_CALL) {
			showProgress();
			handleActionClick(AdInfos.CALL, mAdInfos.getVideoclickThrough(), null);
		} else if(mAdInfos.getActionMode() == AdInfos.ACTION_MODE_DOWNLOAD) {
			if(mAdInfos != null) {
				lockClickEvents(false);
				cancelTimer();
				showProgress();
				// 20131001 다운로드, 전화에 한해서 클릭태그 전송시 각각의 액션에 대한 Tracking tag를 전송한다.(화면클릭태그는 실제주소를 전송해서 오류발생함)
				// 2013년 9월 30일 오후 6:33 메일 확인
				String appTagUrl = mAdInfos.getTrackingUrl(AdInfos.DOWNLOAD) + getActionButtonParameter();
				mConnectionManager.sendRequest(REQUEST_SEND_TAG, appTagUrl, null);
				downloadApp(mAdInfos.getVideoclickThrough());
			}
		} else {
			showBrowserDialog(handleInfo, (mAdInfos != null?mAdInfos.getAdTitle() : ""), pageUrl);
		}
	}
	
	
	private String getActionButtonParameter() {
		String result = "";
		
		result = "&lq=" + String.valueOf(mLastSendedTag) + "&pay=" + (mIsChargeTagSendSucceed? "1": "0");
		
		return result;
	}
	
	
	private void showBrowserDialog(String path, String title, String pageUrl) {
		mIsClickviewerShown = true;
		if(mAdInfos.getBrowserMode().equals(AdInfos.BROWSER_MODE_DEFAULT_BROWSER)) {
			// 실제 브라우저로 넘기는 부분
			initializeVideoView();
			mIsClickviewerShown = true;
			Intent i = new Intent(Intent.ACTION_VIEW); 
			Uri u = Uri.parse(path); 
			i.setData(u);
			mActivity.startActivity(i);
		} else {
			BKDialog dialog = new BKDialog();
			dialog.setOnDialogStateListener(new OnDialogStateListener() {
				
				@Override
				public void onDialogShown() {
					BKLog.w("------- Dialog show");
				}
				
				@Override
				public void onDialogDismissed() {
					BKLog.w("------- Dialog dismissed");
				}
			});
			
//			dialog.setMargin(mDialogMarginRate);
			Intent intent = new Intent(mContext, dialog.getClass());
			intent.putExtra(BKDialog.KEY_LANDING_PAGE_URL, path);
			intent.putExtra(BKDialog.KEY_LANDING_PAGE_REAL_URL, pageUrl);
			intent.putExtra(BKDialog.KEY_LANDING_PAGE_TITLE, title);
			
			mActivity.startActivityForResult(intent, BKDialog.ACTION_CLICKVIEWER);
		}
	}
	
	private void addSnsShareView(ArrayList<SnsShare> list) {
		mSnsBottomLayout = new RelativeLayout(mContext); //  SNS Sahre 기능을 사용하는경우 이 layout을 보여줌
		
		RelativeLayout.LayoutParams snsBottomLayoutParam = 
			new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		snsBottomLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		snsBottomLayoutParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		snsBottomLayoutParam.setMargins(0, 5, 5, 0);
		
		
		mSnsShareButton = new ImageButton(mContext);
		mSnsShareButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mIsButtonClickable) {
					mSnsShareButton.setVisibility(View.GONE);
					mSnsShareContentLayout.setVisibility(View.VISIBLE);
				}
			}
		});
		
		mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.SNS_SHARE), mSnsShareButton, mAdInfos.isIconShowDirectly(AdInfos.SNS_SHARE));
		
		LinearLayout.LayoutParams snsShareButtonParam = 
			new LinearLayout.LayoutParams(mButtonSize, mButtonSize);
		snsShareButtonParam.setMargins(0, 5, 5, 0);
		
		mSnsBottomLayout.addView(mSnsShareButton, snsShareButtonParam);
		
		mSnsShareContentLayout = new LinearLayout(mContext); // SNS Share 버튼 클릭시 나오는 Layout.
		mSnsShareContentLayout.setOrientation(LinearLayout.VERTICAL); 
		mSnsShareContentLayout.setBackgroundColor(Color.parseColor("#E6171717"));
		
		LinearLayout.LayoutParams snsShareContentLayoutParam = 
			new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		int padding = (int) Math.round(mButtonSize / 7);
		mSnsShareContentLayout.setPadding(padding, padding, padding, padding);
		
		LinearLayout snsShareContentMainLayout = new LinearLayout(mContext); // SNS Share시 나오는 Layout의 내용을 담을 Layout
		snsShareContentMainLayout.setOrientation(LinearLayout.VERTICAL); 
		snsShareContentMainLayout.setGravity(Gravity.CENTER);
		
		LinearLayout.LayoutParams snsShareContentMainLayoutParam = 
			new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		
		// SNS Buttons put into SNS button container.
		LinearLayout snsButtonContainer = new LinearLayout(mContext);
		snsButtonContainer.setOrientation(LinearLayout.HORIZONTAL);
		snsButtonContainer.setGravity(Gravity.CENTER);
		
		LinearLayout.LayoutParams snsButtonContainerParam =
			new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
		snsButtonContainerParam.setMargins(0, (int) Math.round(mButtonSize / 6), 0, (int) Math.round(mButtonSize / 6));
		
		for(int i = 0; i < list.size(); i++) {
			ImageButton snsBtn = new ImageButton(mContext);
			mImageDownloader.download(list.get(i).getIconUrl(), snsBtn, true);
			final SnsShare snsInfo = list.get(i);
			snsBtn.setOnClickListener(new OnClickListener() {
				
				@Override
				public void onClick(View v) {
					if(mAdInfos != null && mIsButtonClickable) {
						handleSnsClick(snsInfo);
					}
					
				}
			});
			
			
			LinearLayout.LayoutParams snsBtnParam = new LinearLayout.LayoutParams(mButtonSize, mButtonSize);
			if(i == 0) {
				snsBtnParam.setMargins((int) Math.round(mButtonSize / 5), 0, (int) Math.round(mButtonSize / 5), 0);
			} else {
				snsBtnParam.setMargins(0, 0, (int) Math.round(mButtonSize / 5), 0);
			}
			
			snsButtonContainer.addView(snsBtn, snsBtnParam);
		}
		
		ImageButton cancelButton = new ImageButton(mContext);
		mImageDownloader.download(mAdInfos.getIconUrl(IconInfoParser.ICON_SNS_CANCEL), cancelButton, true);
		
		cancelButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mIsButtonClickable) {
					mSnsShareContentLayout.setVisibility(View.GONE);
					mSnsShareButton.setVisibility(View.VISIBLE);
				}
			}
		});
		
		
		LinearLayout.LayoutParams cancelButtonParam =
			new LinearLayout.LayoutParams((int) Math.round(mButtonSize * 0.8), (int) Math.round(mButtonSize * 0.8));
		cancelButtonParam.setMargins((int) Math.round((mButtonSize / 5) * 1.5), 0, 0, 0);
		
		snsButtonContainer.addView(cancelButton, cancelButtonParam);
		
		snsShareContentMainLayout.addView(snsButtonContainer, snsButtonContainerParam);
		
		
		mSnsShareContentLayout.setVisibility(View.GONE);
		mSnsShareContentLayout.addView(snsShareContentMainLayout, snsShareContentMainLayoutParam);
		mSnsBottomLayout.addView(mSnsShareContentLayout, snsShareContentLayoutParam);
		mVideoLayout.addView(mSnsBottomLayout, snsBottomLayoutParam);
	}
	
	private void handleSnsClick(SnsShare snsInfo) {
		hideProgress();
		mIsSnsShareClicked = true;
		String snsName = snsInfo.getSnsName();
		if(!snsName.equals("etc")) {
			if(mMediaPlayer != null) {
				mMediaPlayer.release();
			}
			mIsDawinPlaying = false;
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_BY_SNS_SHARE);
			}
			
			mConnectionManager.sendRequest(REQUEST_SEND_TAG, snsInfo.getClickTracking() + getActionButtonParameter(), null);
		}
		
		if(snsName.equals("kakaoTalk")) {
			if(mIsKakaoTalkInstalled) {
				try {
					CommonUtils.shareKakao(mActivity, CommonUtils.KAKAO_TALK, null, snsInfo.getMessage(), snsInfo.getClickThrough());
					
				} catch(UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			} else {
				downloadApp("market://details?id=com.kakao.talk");
			}
		} else if(snsName.equals("kakaoStory")) {
			if(mIsKakaoStoryInstalled) {
				try {
					CommonUtils.shareKakao(mActivity, CommonUtils.KAKAO_STORY, null, snsInfo.getMessage(), snsInfo.getClickThrough());
				} catch(UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			} else {
				downloadApp("market://details?id=com.kakao.story");
			}
		} else if(snsName.equals("etc")) {
			BKLog.i("etc button clicked~~~~~~");
			if(!mIsSnsEtcButtonClicked) {
				mConnectionManager.sendRequest(REQUEST_SEND_TAG, snsInfo.getClickTracking() + getActionButtonParameter(), null);
				mIsSnsEtcButtonClicked = true;
			} else {
				BKLog.w("Etc already clicked!!");
			}
			
			CommonUtils.setTextToPrimaryClipboard(mContext, snsInfo.getClickThrough(), "복사됐습니다.");
			mSnsShareContentLayout.setVisibility(View.GONE);
			mSnsShareButton.setVisibility(View.VISIBLE);
		} else {
			boolean flag = false;
			StringBuilder sb = new StringBuilder();
			if(snsName.equals("facebook")) {
				sb.append("http://www.facebook.com/sharer/sharer.php?").append("&u=").append(snsInfo.getClickThrough());
				flag = true;
			} else if(snsName.equals("twitter")) {
				sb.append("https://twitter.com/intent/tweet?text=").append(snsInfo.getMessage());
				sb.append("&url=").append(snsInfo.getClickThrough());
				flag = true;
			}
			
			Intent i = new Intent(Intent.ACTION_VIEW); 
			Uri u = Uri.parse(flag ? sb.toString() : snsInfo.getClickThrough()); 
			i.setData(u); 
			mActivity.startActivity(i);
		}
	}
	
	/**
	 * Dawin 개편
	 * Ticker 추가기능 관련 메소드
	 */
	private void addTickerView(ArrayList<TickerAd> list) {
		mTickerButton = new ImageButton(mContext);
		mTickerButton.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if(mAdInfos != null) {
					lockClickEvents(false);
					cancelTimer();
					if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
						mMediaPlayer.pause();
					}
					showProgress();
					handleTickerClick();
				}
				
			}
		});
		mTickerButton.setVisibility(View.GONE);
		RelativeLayout.LayoutParams tickerButtonParam =
			new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
		mVideoLayout.addView(mTickerButton, tickerButtonParam);
	}
	
	private void showTicker() {
		if(!mIsTickerShowing) {
			// TODO : 현재 보이지 않는 상태이므로 티커관련 변수 초기화 후 보여줌.
			if(mTicker != null) {
				startTickerTimer();
			}
		}
	}
	
	private void handleTickerView() {
		TickerInfo info = mTicker.getTickerList().get(mCurrentTickerNum);
		
		if(mIsTickerShowing) {
			changeTickerByOrientation();
		} else {
			// ticker를 보여줘야하는 시점!!
			mTickerButton.setBackgroundDrawable(new BitmapDrawable(info.getBitmap()));
			
			RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(info.getWidth(mCurrentOrientation), info.getHeight(mCurrentOrientation));
			param = changePositionByNumber(param, info.getPosition());
			mTickerButton.setLayoutParams(param);
			mTickerButton.setVisibility(View.VISIBLE);
			mTickerButton.refreshDrawableState();
			mCurrentShowingTickerOrientation = mCurrentOrientation;
			mIsTickerShowing = true;
			BKLog.e("ShowTicker!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! in HandleTickerView");
		}
	}
	
	// 20141222 티커 가로/세로 전환시 사이즈 변하지 않는 문제로 추가함. 공통 라이브러리는 Button 2개를 번갈아 보여주는 형식이지만, 아프리카는 일단 버튼 하나로 컨트롤 시도함.
	private void changeTickerByOrientation() {
		if(mTicker != null && mTicker.getTickerList() != null && mTicker.getTickerList().size() > 0) { // 20141121 비정상인경우 걸러내는 것으로함.
			RelativeLayout.LayoutParams param = 
				new RelativeLayout.LayoutParams(mTicker.getTickerList().get(mCurrentTickerNum).getWidth(mCurrentOrientation), 
					mTicker.getTickerList().get(mCurrentTickerNum).getHeight(mCurrentOrientation));
			param = changePositionByNumber(param, mTicker.getTickerList().get(mCurrentTickerNum).getPosition());
			if(mCurrentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
				mTickerButton.setLayoutParams(param);
			} else {
				mTickerButton.setLayoutParams(param);
			}
		}
	}
	
	public void removeTickerView() {
		mTickerButton.setVisibility(View.GONE);
		mIsTickerShowing = false;
		mCurrentShowingTickerOrientation = -1;
		mCurrentTickerNum++;
		if(mCurrentTickerNum >= mTicker.getTickerList().size()) {
			cancelTickerTimer();
			initializeTicker();
		}
	}
	
	private void handleTickerClick() {
		BKLog.e("handle Ticker click!!");
		mIsDawinPlaying = false;
		lockClickEvents(false);
		cancelTimer();
		cancelTickerTimer();
		
		if(mIsTickerShowing && mTicker != null) {
			final TickerInfo info = mTicker.getTickerList().get(mCurrentTickerNum);
			if(info != null) {
				String program = info.getProgram();
				
				if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_BY_TICKER);
				mIsTickerClicked = true;
				if(program.equals("download")) {
					mConnectionManager.sendRequest(REQUEST_SEND_TAG, info.getClickTracking() + getActionButtonParameter(), null);
					lockClickEvents(false);
					downloadApp(info.getClickThrough().trim());
				} else if(program.equals("call")) {
					final String phoneNumber = info.getClickThrough();
					if(mCurrentServiceState == ServiceState.STATE_IN_SERVICE) {
						AlertDialog dialog = CommonUtils.getAlertDialog(mActivity, null, phoneNumber, "취소", "통화", new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
								if(mPlayFinishListener != null) {
									mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_TICKER);
								}
							}
						} , new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
								mCurrentCallState = CALL_STATE_OUTGOING;
								mConnectionManager.sendRequest(REQUEST_SEND_TAG, info.getClickTracking() + getActionButtonParameter(), null);
								CommonUtils.callTo(mActivity, phoneNumber);
							}
						});
						dialog.setOnKeyListener(new Dialog.OnKeyListener() {

				            @Override
				            public boolean onKey(DialogInterface arg0, int keyCode,
				                    KeyEvent event) {
				                if (keyCode == KeyEvent.KEYCODE_BACK) {
				                    arg0.dismiss();
				                    if(mPlayFinishListener != null) {
				                    	BKLog.i("Back Key pressed in call dialog-can make call case");
										mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_TICKER);
									}
				                }
				                return true;
				            }
				        });
						dialog.show();
						TextView msg = (TextView) dialog.findViewById(android.R.id.message);
						msg.setGravity(Gravity.CENTER);
						
					} else {
						AlertDialog dialog = CommonUtils.getAlertDialog(mActivity, null, "전화 기능을 이용할 수 없는 상태입니다.", "확인", null, new DialogInterface.OnClickListener() {
							
							@Override
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
								if(mPlayFinishListener != null) {
									mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_TICKER);
								}
							}
						}, null);
						dialog.show();
						TextView msg = (TextView) dialog.findViewById(android.R.id.message);
						msg.setGravity(Gravity.CENTER);
					}
					
				} else {
					try {
						String tickerBtnUrl = info.getClickTracking() + getActionButtonParameter();
						Intent i = new Intent(Intent.ACTION_VIEW); 
						Uri u = Uri.parse(tickerBtnUrl);
						i.setData(u); 
						mActivity.startActivity(i);
					} catch(Exception e) {
						e.printStackTrace();
						if(mPlayFinishListener != null) {
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
						}
					}
				}
			} else {
				if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
			}
		} else {
			if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
		}
	}
	
	private void downloadTickerImage(ArrayList<TickerAd> list) {
		ArrayList<String> tickerUrl = new ArrayList<String>();
		
		for(int i = 0; i < list.size(); i++) {
			tickerUrl.add(list.get(i).getImageUrl());
		}
		
		if(tickerUrl.size() > 0) {
			BKImageDownloader downloader = new BKImageDownloader(mContext);
			downloader.setOnBitmapDownloadFinishListener(new OnBitmapDownloadFinishListener() {
				
				@Override
				public void onBitmapDownloadFinished(ArrayList<Bitmap> bitmaps) {
					BKLog.e("onBitmapDownloadFinished---- bitmap count : " + bitmaps.size());
					if(bitmaps != null && bitmaps.size() > 0) {
						mTicker = new TickerAdBuilder(mAdInfos.getTickerList(), bitmaps).build(mCurrentOrientation, 
							new ScreenSize((mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ? mPortParentWidth : mLandParentWidth), 
								(mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ? mPortParentHeight : mLandParentHeight)));
						
						if(!mIsTickerShowing && isDawinAdPlaying()) {
							showTicker();
						}
					}
					
				}
			});
			downloader.downloadBitmaps(tickerUrl);
		} else {
			return;
		}
	}
	
	public boolean isDawinAdPlaying() {
		return mIsDawinPlaying;
	}
	
	/**
	 * @deprecated
	 * this method deprecated.
	 * @param orientation : orientation to set mode
	 * @param mode : video display mode
	 * @see BKVideoView, Configuration
	 */
	public void setVideoMode(int orientation, int mode) {
		switch(orientation) {
			case Configuration.ORIENTATION_LANDSCAPE:
//				mLandscapeVideoMode = mode;
				break;
				
			case Configuration.ORIENTATION_PORTRAIT:
//				mPortraitVideoMode = mode;
				break;
		}
//		mVideoView.setVideoMode(orientation, mode);
	}
	
	
	/**
	 * show ad with given parameters.
	 * @param gcd : goods code
	 * @param mcd : media code
	 * @param pcd : page code
	 * @param scd : screen code
	 * @param ccd : category code
	 * @return : -1 returns when any parameter is null or 0 length. otherwise returns 0.
	 */
	
	public int showAd(String gcd, String mcd, String pcd, String scd, String ccd) {
		if(gcd == null || gcd.equals("") || mcd == null || mcd.equals("") || pcd == null || pcd.equals("") || scd == null || scd.equals("") || ccd == null || ccd.equals("")) {
			if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			destroy();
			return -1;
		}
		
		mAdInfoParameter = getAdInfoParameter(gcd, mcd, pcd, scd, ccd);
		if(mAdInfoParameter == null) {
			if(mPlayFinishListener != null) mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			destroy();
			return -1;
		}
		
		showProgress();
		mAdinfoRequestUrl = (mDawinServerType == DawinConfig.DAWIN_SERVER_TEST?AD_INFO_TEST_URL:AD_INFO_URL);
		mConnectionManager.sendRequest(REQUEST_AD_INFOS, mAdinfoRequestUrl, mAdInfoParameter);
		
		if(mErrorHandler.isFailedWorkAvailable()) {
			new Handler().postDelayed(new Runnable() {

				@Override
				public void run() {
					mErrorHandler.sendFailedRequest();
				}
				
			}, 1000);
			
		}
		return 0;
	}
	
	public void setDialogMarginRate(int marginRate) {
		mDialogMarginRate = marginRate;
	}
	
	public void showTestAd(String url) {
		showProgress();
		mConnectionManager.sendRequest(REQUEST_AD_INFOS, url, null);
	}
	
	private JSONObject getAdInfoParameter(String gcd, String mcd, String pcd, String scd, String ccd) {
		String uid = CommonUtils.getStringPreference(mContext, DawinConfig.KEY_UID);
		
		JSONObject result = new JSONObject();
		try {
			result.put("gcd", gcd);
			result.put("mcd", mcd);
			result.put("pcd", pcd);
			result.put("scd", scd);
			result.put("ccd", ccd);
			// 20130731 버전코드 추가함.
			result.put("ver", "2.0");
			// 20131125 queryString 뒤에 UID를 붙여서 요청보내는 작업 추가함(preferences에 저장된 UID 이용)
			if(uid != null && !uid.equals("")) {
				result.put("uid", uid);
			}
			
		} catch(JSONException e) {
			result = null;
		}
		
		return result;
	}
	
	
	
	private void prepareVideo() {
		if(mAdInfos == null) {
			mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
			return;
		}
		this.setVisibility(View.VISIBLE);
//		mMediaController = new MediaController(mContext);
//		mMediaController.setAnchorView(mVideoPlayer);
//		mVideoView.setMediaController(mMediaController);
		
		if(mAdInfos.getMediaFileUrl() == null) {
			if(mPlayFinishListener != null) {
				BKLog.e("media file url null");
				mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
			}
		}
		openVideo();
		// ##Ben afreeca test
//		mSurfaceView.requestFocus();
		
	}
	
	public void onConfigurationChanged() {
		int orientation;
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
			orientation = Configuration.ORIENTATION_PORTRAIT;
		} else {
			orientation = Configuration.ORIENTATION_LANDSCAPE;
		}
	}
	
	
	private void showProgress() {
		lockClickEvents(false);
		mProgress.setVisibility(View.VISIBLE);
	}
	
	private void hideProgress() {
		lockClickEvents(true);
		mProgress.setVisibility(View.GONE);
	}
	
	
	/**
	 * lock clickable views
	 * @param isClickable : false to lock buttons
	 */
	private void lockClickEvents(boolean isClickable) {
		mVideoLayout.setClickable(isClickable);
		mFacebookButton.setClickable(isClickable);
		mTwitterButton.setClickable(isClickable);
		mSkipButton.setClickable(isClickable);
		mEventButton.setClickable(isClickable);
		mCallButton.setClickable(isClickable);
		mMapButton.setClickable(isClickable);
		mDownloadButton.setClickable(isClickable);
		// 20141222 클릭이벤트 락걸때 추가된 티커와 sns 함께 적용함.(20141216 공통라이브러리 적용본)
		if(mTickerButton != null) mTickerButton.setClickable(isClickable);
		if(mSnsShareButton != null) mSnsShareButton.setClickable(isClickable);
		mIsButtonClickable = isClickable;
	}
	
	
	
	private void initializeVideoView() {
		// remove or stop schedulers
		cancelTimer();
		mCurrentCallState = CALL_STATE_IDLE;
		mIsClickviewerShown = false;
		mIsOnPauseCalled = false;
		mIsSnsShareClicked = false;
		mIsSnsEtcButtonClicked = false;
		
		// init ticker variables
		mIsDawinPlaying = false;
		mIsTickerShowing = false;
		
		// remove ad informations
		mAdInfos = null;
		// initialize tag
		mIsStartTagSended = false;
		// initialize videoview click
		mIsVideoClickProcessing = false;
		// 비디오 시작했을 때 수행하는 동작 한번만 할 수 있도록 체크하는 변수 초기화
		mIsVideoPlaying = false;
		
		// 과금 관련 변수 초기화
		mIsChargeTagSended = false;
		mIsChargeTagSendSucceed = false;
		
		// initialize video ratio
		mWidthRatio = -1;
		mHeightRatio = -1;
		
		// initialize video size
		mVideoWidth = -1;
		mVideoHeight = -1;
		
		// initialize fixed video size
		mLandFixedWidth = -1;
		mLandFixedHeight = -1;
		mPortFixedWidth = -1;
		mPortFixedHeight = -1;
		
		// 태그 전송여부 확인용 변수 초기화
		mLastSendedTag = 0;
		mCurrentQuarter = 1;
		if(mVideoLayout != null) {
			mVideoLayout.removeAllViews();
		}
		this.removeAllViews();
		initAdditionalView();
		setViews();
		
		mIsPlayerInitialized = true;
	}
	
	private void initializeTicker() {
		BKLog.e("initializeTicker()");
		if(mTicker != null && mTicker.getTickerList() != null) {
			for(int i = 0; i < mTicker.getTickerList().size(); i++) {
				TickerInfo info = mTicker.getTickerList().get(i);
				Bitmap bitmap = info.getBitmap();
				if(bitmap != null) {
					bitmap.recycle();
					BKLog.i(i + " bitmap recycled.");
				}
			}
			mTicker = null;
		}
		
		
		
		mIsTickerShowing = false;
		mCurrentTickerNum = 0;
		mCurrentShowingTickerOrientation = -1;
		if(mTickerButton != null) {
			mTickerButton.setVisibility(View.GONE);
		}
		
	}
	
	private void checkIconImage(int actionMode) {
		if(mAdInfos == null) {
			return;
		}
		switch(actionMode) {
			case AdInfos.ACTION_MODE_SNS:
				if(mAdInfos.getIconUrl(AdInfos.FACEBOOK) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.FACEBOOK), mFacebookButton, mAdInfos.isIconShowDirectly(AdInfos.FACEBOOK));
				}
				
				if(mAdInfos.getIconUrl(AdInfos.TWITTER) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.TWITTER), mTwitterButton, mAdInfos.isIconShowDirectly(AdInfos.TWITTER));
				}
				break;
				
			case AdInfos.ACTION_MODE_CALL:
				if(mAdInfos.getIconUrl(AdInfos.CALL) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.CALL), mCallButton, mAdInfos.isIconShowDirectly(AdInfos.CALL));
				}
				break;
				
			case AdInfos.ACTION_MODE_DOWNLOAD:
				if(mAdInfos.getIconUrl(AdInfos.DOWNLOAD) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.DOWNLOAD), mDownloadButton, mAdInfos.isIconShowDirectly(AdInfos.DOWNLOAD));
				}
				break;
				
			case AdInfos.ACTION_MODE_EVENT:
				if(mAdInfos.getIconUrl(AdInfos.EVENT) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.EVENT), mEventButton, mAdInfos.isIconShowDirectly(AdInfos.EVENT));
				}
				break;
				
			case AdInfos.ACTION_MODE_MAP:
				if(mAdInfos.getIconUrl(AdInfos.MAP) != null) {
					mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.MAP), mMapButton, mAdInfos.isIconShowDirectly(AdInfos.MAP));
				}
				break;
			
			// 20130930 Action button이 없는 경우도 있다고 하여 ACTION_MODE_NONE 추가
			case AdInfos.ACTION_MODE_NONE:
				// DO NOTHING yet.
				break;
				
		}
		
//		if(mAdInfos.getIconUrl(AdInfos.SKIP) != null) {
//			mImageDownloader.download(DawinConfig.IMG_SKIP_URL, mSkipButton, false);
//		}
		// 20140919 아이콘 이미지 하드코딩 제거함. 이미지 체크 필요!!
		if(mAdInfos.isAvailable(AdInfos.SKIP)) {
			if(mAdInfos.getIconUrl(AdInfos.SKIP) != null) {
				mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.SKIP), mSkipButton, false);
			}
		}
		
		if(mAdInfos.isAvailable(AdInfos.SKIP_DESCRIPTION)) {
			if(mAdInfos.getIconUrl(AdInfos.SKIP_DESCRIPTION) != null) {
				mImageDownloader.download(mAdInfos.getIconUrl(AdInfos.SKIP_DESCRIPTION), mSkipDescriptionButton, true);
			}
		}
	}
	
	private void showActionLayout() {
		if(mAdInfos != null) {
			switch(mAdInfos.getActionMode()) {
				case AdInfos.ACTION_MODE_SNS:
					mSnsLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_CALL:
					mCallLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_DOWNLOAD:
					mDownloadLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_EVENT:
					mEventLayout.setVisibility(View.VISIBLE);
					break;
					
				case AdInfos.ACTION_MODE_MAP:
					mMapLayout.setVisibility(View.VISIBLE);
					break;
			}
		}
	}
	
	
	public int destroy() {
		cancelTimer();
		mVideoLayout.removeAllViews();
		this.removeAllViews();
		if(mMediaPlayer != null) {
			try {
				// 20140113 이미 release된 경우거나 initialize되지 않은 경우 오류발생하므로 일차적 보호막 형성..
				if(mIsPlayerInitialized) {
					if(mMediaPlayer.isPlaying()) {
						mMediaPlayer.pause();
						mMediaPlayer.stop();
					}
				}
				mMediaPlayer.reset();
			} catch(IllegalStateException e) {
				// 이 오류가 나오면 이미 release가 됐거나 initialize가 되지 않은 상황임.
				e.printStackTrace();
			} catch(Exception e) {
				e.printStackTrace();
			}
			mMediaPlayer.release();
			mMediaPlayer = null;
		}
		System.gc();
		mIsPlayerInitialized = false;
		return 0;
	}
	
	private void initAdditionalView() {
		if(mSnsBottomLayout != null) {
			mSnsBottomLayout.removeAllViews();
			mSnsBottomLayout = null;
		}
		initializeTicker();
		mIsDawinPlaying = false;
	}
	
	private void releaseAllListeners() {
		mPlayFinishListener = null;
		mErrorListener = null;
		mPreparedListener = null;
		mTimeListener = null;
		mTickerTimeListener = null;
	}
	
	
	private void showCallDialog(String phoneNumber) {
		if(mAdInfos == null) {
			mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
			destroy();
			return;
		}
		
		// 20130624 추가. 전화 버튼을 눌렀을 때 요청 보내는 걸로 수정
		final String callTracking = mAdInfos.getTrackingUrl(IconInfoParser.ICON_CALL) + getActionButtonParameter();
		hideProgress();
		destroy();
		final String num = phoneNumber;
		if(mCurrentServiceState == ServiceState.STATE_IN_SERVICE) {
			AlertDialog dialog = CommonUtils.getAlertDialog(mActivity, null, phoneNumber, "취소", "통화", new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_ACTION);
					}
				}
			} , new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					mCurrentCallState = CALL_STATE_OUTGOING;
					mIsClickviewerShown = true;
					mConnectionManager.sendRequest(REQUEST_PHONE_CLICK, callTracking, null);
					CommonUtils.callTo(mActivity, num);
				}
			});
			dialog.setOnKeyListener(new Dialog.OnKeyListener() {

	            @Override
	            public boolean onKey(DialogInterface arg0, int keyCode,
	                    KeyEvent event) {
	                if (keyCode == KeyEvent.KEYCODE_BACK) {
	                    arg0.dismiss();
	                    if(mPlayFinishListener != null) {
	                    	BKLog.i("Back Key pressed in call dialog-can make call case");
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AFTER_ACTION);
						}
	                }
	                return true;
	            }
	        });
			dialog.show();
			TextView msg = (TextView) dialog.findViewById(android.R.id.message);
			msg.setGravity(Gravity.CENTER);
			
		} else {
			AlertDialog dialog = CommonUtils.getAlertDialog(mActivity, null, "전화 기능을 이용할 수 없는 상태입니다.", "확인", null, new DialogInterface.OnClickListener() {
				
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_CALL_ACTION);
					}
				}
			}, null);
			dialog.setOnCancelListener(new OnCancelListener() {
				
				@Override
				public void onCancel(DialogInterface dialog) {
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_CALL_ACTION);
					}
				}
			});
			dialog.show();
			TextView msg = (TextView) dialog.findViewById(android.R.id.message);
			msg.setGravity(Gravity.CENTER);
		}
	}
	
	
	/**
	 * 화면 클릭 이벤트 등 뷰에 관련된 이벤트 발생이 필요한 경우 반환함.
	 * @return View : VideoView를 담고있는 컨테이너.
	 */
	public View getScreenContainerView() {
		return mVideoLayout;
	}
	
	
	public void setOnPlayFinishListener(OnPlayFinishListener listener) {
		mPlayFinishListener = listener;
	}
	
	public void setOnErrorListener(OnErrorListener listener) {
		mErrorListener = listener;
	}
	
	public void setOnPreparedListener(OnPreparedListener listener) {
		mPreparedListener = listener;
	}
	
	public void setOnVideoInfoReceiveListener(OnVideoInfoReceiveListener listener) {
		mVideoInfoListener = listener;
	}
	
	/*****************************************************************************/
	/*************************test code!!!!!!!!!!!!!!!!***************************/
	/*****************************************************************************/
	public String getXmlString() {
		return xmlString;
	}
	/*****************************************************************************/
	/*************************test code!!!!!!!!!!!!!!!!***************************/
	/*****************************************************************************/
	
	@Override
	public void onRequestFinished(int whichRequest, HttpResponse result, String extractString) {
		BKLog.i("Request success!!!!!!!");
		switch(whichRequest) {
			case REQUEST_AD_INFOS:
				BKLog.i("Request ad info receive success!!");
				// 새로 정보를 받은 경우 과금테그 flag 초기화함.
				mIsChargeTagSendSucceed = false;
				xmlString = extractString;
				BKAdInfoParser parser = new BKAdInfoParser(extractString);
				mAdInfos = parser.parse();
				
				if(mAdInfos != null && !mAdInfos.isParsingProblemOccured()) { // 20141216 파싱문제여부 체크구문 추가. 문제가 있는경우 True 리턴되므로 false인 경우 진행함.
					mAdInfoRetryCount = 0; // 현재 분기문 조건에 만족하는 경우는 정상이라고 판단 하므로 기존에 변경됐을지도 모르는 재시도횟수 카운트용 변수 초기화
					if(mAdInfos != null) {
						String adId = mAdInfos.getAdId();
						
						if(adId != null && Integer.parseInt(adId) != DawinConfig.SERVER_MSG_NO_APPLICABLE_AD) {
							BKLog.e("Action mode : " + mAdInfos.getActionMode());
							if(mAdInfos.isTickerAvailable()) {
								downloadTickerImage(mAdInfos.getTickerList());
							}
							checkIconImage(mAdInfos.getActionMode());
							prepareVideo();
							
							try {
								if(mAdInfos.isTickerAvailable()) {
									addTickerView(mAdInfos.getTickerList());
								}
							} catch(Exception e) {
								e.printStackTrace();
							}
						} else {
							if(mPlayFinishListener != null) {
								mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_NO_APPLICABLE_AD);
							}
							hideProgress();
							DawinAdPlayer.this.setVisibility(View.GONE);
						}
					}
				} else {
					// 20141216 최홍석팀장님 --> 파싱 문제시 3회 재시도로 수정지시함. 여기서 3회 재시도 구문 추가.
					BKLog.w("Parsing problem occured!!!");
					if(mAdInfoRetryCount >= MAX_RETRY_COUNT) {
						// finish retry. 뷰 종료 또는 에러처리
						mAdInfoRetryCount = 0; // 맥시멈 시도횟수 초과로 시도횟수체크용 변수 초기화
						hideProgress();
//						Toast.makeText(mContext, "광고 정보 수신 실패", Toast.LENGTH_SHORT).show();
						if(mPlayFinishListener != null) {
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AD_INFO_RECEIVE_FAIL);
						}
						// 광고정보요청 실패 로그 서버전송.
						String errorUrl = (DawinConfig.isDebugMode?ADINFO_ERROR_LOG_DEV:ADINFO_ERROR_LOG_REL) + mAdinfoRequestUrl;
						mErrorHandler.sendErrorTag(errorUrl);
					} else {
						mAdInfoRetryCount++;
						mConnectionManager.sendRequest(REQUEST_AD_INFOS, mDawinServerType == DawinConfig.DAWIN_SERVER_TEST?AD_INFO_TEST_URL:AD_INFO_URL, mAdInfoParameter);
						BKLog.e("Parsing failed. retry..( " + mAdInfoRetryCount + ")");
					}
				}
				
				// 20131010 추출한 스트링에 문제가 있는 상황인지 판단할 기준을 추가함.
				/*if(parser.canParse()) {
					mAdInfos = parser.parse();
					if(mAdInfos != null) {
						String adId = mAdInfos.getAdId();
						
						if(adId != null && Integer.parseInt(adId) != DawinConfig.SERVER_MSG_NO_APPLICABLE_AD) {
							
							
							BKLog.e("Action mode : " + mAdInfos.getActionMode());
							if(mAdInfos.isTickerAvailable()) {
								downloadTickerImage(mAdInfos.getTickerList());
							}
							checkIconImage(mAdInfos.getActionMode());
							
							prepareVideo();
						} else {
							if(mPlayFinishListener != null) {
								mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_NO_APPLICABLE_AD);
							}
							hideProgress();
							DawinAdPlayer.this.setVisibility(View.GONE);
						}
					}
				} else {
					// 통신은 성공했으나 파싱에서 문제가 생기는 경우 기타이유로 종료 처리함.
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
					}
				}*/
				
				break;
				
			case REQUEST_START:
				BKLog.i("Start tag send success");
				break;
				
			case REQUEST_QUARTER:
				BKLog.i("Quarter tag send success");
				break;
				
			case REQUEST_QUEARTER2:
				BKLog.i("Quarter2 tag send success");
				break;
				
			case REQUEST_QUEARTER3:
				BKLog.i("Quarter3 tag send success");
				break;
				
			case REQUEST_FINISHED:
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
				}
				destroy();
				BKLog.i("Finish tag send success");
				break;
				
			case REQUEST_SKIP:
				BKLog.i("Skip tag send success");
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_SKIP);
				}
				destroy();
				break;
				
			case REQUEST_ERROR:
				BKLog.i("Error tag send success");
				break;
				
			case REQUEST_CHARGE:
				mIsChargeTagSendSucceed = true;
				if(mIsQuarterMinAd) {
					if(mAdInfos != null) {
						mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
					} 
				} else {
					hideProgress();
				}
				BKLog.i("Charge tag send success");
				
				break;
				
			case REQUEST_PHONE_CLICK:
				BKLog.i("PhoneTag send success");
				break;
				
			case REQUEST_SEND_TAG:
				BKLog.i("tag send success");
				break;
			
		}
	}

	@Override
	public void onRequestError(int whichRequest, int errorCode, String message) {
		BKLog.e("Request error!!!!!!!");
		BKLog.e("Error code : " + errorCode + ", request : " + whichRequest);
		
		switch(whichRequest) {
			case REQUEST_AD_INFOS:
				if(errorCode == BKConnectionManager.NETWORK_DISCONNECTED) {
//					Toast.makeText(mContext, "네트워크가 끊어졌습니다. 상태 확인 후 다시 이용해 주세요", Toast.LENGTH_SHORT).show();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_NETWORK_DISCONNECTED);
					}
					destroy();
				} else {
					if(mAdInfoRetryCount >= MAX_RETRY_COUNT) {
						// finish retry. 뷰 종료 또는 에러처리
						mAdInfoRetryCount = 0; // 맥시멈 시도횟수 초과로 시도횟수체크용 변수 초기화
						hideProgress();
//						Toast.makeText(mContext, "광고 정보 수신 실패", Toast.LENGTH_SHORT).show();
						if(mPlayFinishListener != null) {
							mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_AD_INFO_RECEIVE_FAIL);
						}
						// 광고정보요청 실패 로그 서버전송.
						String errorUrl = (DawinConfig.isDebugMode?ADINFO_ERROR_LOG_DEV:ADINFO_ERROR_LOG_REL) + mAdinfoRequestUrl;
						mErrorHandler.sendErrorTag(errorUrl);
					} else {
						mAdInfoRetryCount++;
						mConnectionManager.sendRequest(REQUEST_AD_INFOS, mDawinServerType == DawinConfig.DAWIN_SERVER_TEST?AD_INFO_TEST_URL:AD_INFO_URL, mAdInfoParameter);
						BKLog.e("Ad info receive failed. retry..( " + mAdInfoRetryCount + ")");
					}
				}
				break;
				
			case REQUEST_START:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=2");
				}
				
				break;
				
			case REQUEST_QUARTER:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=3");
				}
				break;
				
			case REQUEST_QUEARTER2:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=4");
				}
				break;
				
			case REQUEST_QUEARTER3:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=5");
				}
				break;
				
			case REQUEST_FINISHED:
				// 정상종료처럼 바로 진행
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=6");
				}
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
				}
				destroy();
				break;
				
			case REQUEST_SKIP:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=7");
				}
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_SKIP);
				}
				destroy();
				break;
				
			case REQUEST_ERROR:
				// do nothing
				break;
				
			case REQUEST_CHARGE:
				if(mAdInfos != null) {
					mErrorHandler.sendErrorTag(mAdInfos.getErrorUrl() + "&ecd=8");
				}
				handleChargeRequestError(whichRequest);
				break;
				
			case REQUEST_PHONE_CLICK:
				
				break;
				
			case REQUEST_SEND_TAG:
				BKLog.i("tag send error");
				break;
			
		}
		
	}
	
	private boolean handleChargeRequestError(int currRequest) {
		if(mChargeTagRetryCount >= MAX_RETRY_COUNT) {
			// finish retry. save failed list.
			if(mAdInfos != null) {
				mErrorHandler.saveFailedWork(mAdInfos.getChargeTag());
			}
			
			if(mIsQuarterMinAd) {
				if(mAdInfos != null) {
					mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
				}
			} else {
				hideProgress();
				destroy();
			}
			
			return true;
		} else {
			mChargeTagRetryCount++;
			if(mAdInfos != null) {
				mConnectionManager.sendRequest(currRequest, mAdInfos.getEndTag(), null);
			}
			BKLog.e("Ad info receive failed. retry..( " + mChargeTagRetryCount + ")");
			return false;
		}
	}
	
	public void onPause() {
		BKLog.e("onPause dawinPalyer");
		mIsOnPauseCalled = true;
		destroy();
	}
	
	public void onDestroy() {
		destroy();
	}
	
	public void onBackPressed() {
		if(mPlayFinishListener != null && mMediaPlayer != null) {
			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_BACK_KEY_PRESSED);
		}
		destroy();
	}

	@Override
	public void onDialogShown() {
	}
	
	@Override
	public void onDialogDismissed() {
		hideProgress();
	}

	
	
	/****************************************************************************************************************/
	/************************************      Media player works!!    **********************************************/
	/****************************************************************************************************************/
	
	private void openVideo() {
		if(mAdInfos != null && mAdInfos.getMediaFileUrl() != null) {
			// Tell the music playback service to pause
			Intent i = new Intent("com.android.music.musicservicecommand");
			i.putExtra("command", "pause");
			mContext.sendBroadcast(i);
			
			try {
				mMediaPlayer = new MediaPlayer();
				mMediaPlayer.setDataSource(mAdInfos.getMediaFileUrl());
				mMediaPlayer.setDisplay(mSurfaceHolder);
				mMediaPlayer.setOnPreparedListener(this);
				mMediaPlayer.setOnVideoSizeChangedListener(this);
				mMediaPlayer.setOnCompletionListener(this);
				mMediaPlayer.setOnErrorListener(this);
				mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
				mMediaPlayer.setScreenOnWhilePlaying(true);
				mMediaPlayer.prepareAsync();
				BKLog.e("Prepare async");
				// we don't set the target state here either, but preserve the
				// target state that was there before.
			} catch(IOException ex) {
				if(mErrorListener != null) {
					mErrorListener.onError(mMediaPlayer, 0, 0);
				}
				return;
			} catch(IllegalArgumentException ex) {
				if(mErrorListener != null) {
					mErrorListener.onError(mMediaPlayer, 0, 0);
				}
				
				return;
			} catch(Exception e) {
				if(mErrorListener != null) {
					mErrorListener.onError(mMediaPlayer, 0, 0);
				}
				return;
			}
			
		} else {
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
			}
		}
	}
	
	
	// save video size and calculate video ratio
	private void setVideoSize(int width, int height) {
		mVideoWidth = width;
		mVideoHeight = height;

		int max = CommonUtils.getGreatestCommonMeasure(width, height);

		mWidthRatio = width / max;
		mHeightRatio = height / max;
		
		BKLog.i("VideoWidth : " + width + ", height : " + height);
		BKLog.i(mWidthRatio + ":" + mHeightRatio + " source.");
		
		setFixedVideoSize(CommonUtils.getOrientation(mContext));
		mHandler.sendEmptyMessage(MESSAGE_ADJUST_SURFACEVIEW);
		
	}
	
	private void setSurfaceViewSize() {
		if(mVideoWidth != 0 && mVideoHeight != 0) {
			if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_PORTRAIT) {
				if(mPortFixedWidth != 0 && mPortFixedHeight != 0) {
					mSurfaceHolder.setFixedSize(mPortFixedWidth, mPortFixedHeight);
					refreViews();
				}
			} else {
				if(mLandFixedWidth != 0 && mLandFixedHeight != 0) {
					mSurfaceHolder.setFixedSize(mLandFixedWidth, mLandFixedHeight);
					refreViews();
				}
			}
		} else {
			BKLog.e("Video not prepared");
		}
		
	}
	
	private ScreenSize getOptimalVideoSize(int width, int height, int widthRatio, int heightRatio) {
		
		
		ScreenSize size = null;
		if(widthRatio == -1 || heightRatio == -1) {
			// default size
			widthRatio = 16;
			heightRatio = 9;
		}
		
		int resultWidth = 0;
		int resultHeight = 0;
		
		resultWidth = width;
		resultHeight = (width / widthRatio) * heightRatio;
		
		if(resultWidth > width || resultHeight > height) {
			resultWidth = (height / heightRatio) * widthRatio;
			resultHeight = height;
		}
		
		if(CommonUtils.getOrientation(mContext) == Configuration.ORIENTATION_LANDSCAPE) {
			if(mLandFixedWidth == -1 || mLandFixedHeight == -1) {
				mLandFixedWidth = resultWidth;
				mLandFixedHeight = resultHeight;
			} else {
				resultWidth = mLandFixedWidth;
				resultHeight = mLandFixedHeight;
			}
		} else {
			if(mPortFixedWidth == -1 || mPortFixedHeight == -1) {
				mPortFixedWidth = resultWidth;
				mPortFixedHeight = resultHeight;
			} else {
				resultWidth = mPortFixedWidth;
				resultHeight = mPortFixedHeight;
			}
		}
		
		size = new ScreenSize(resultWidth, resultHeight);
		
		return size;
	}
	
	private void refreViews() {
		mFacebookButton.refreshDrawableState();
		mTwitterButton.refreshDrawableState();
		mSkipButton.refreshDrawableState();
		mCallButton.refreshDrawableState();
		mMapButton.refreshDrawableState();
		mEventButton.refreshDrawableState();
		mDownloadButton.refreshDrawableState();
		
		mSnsLayout.refreshDrawableState();
		mEventLayout.refreshDrawableState();
		mCallLayout.refreshDrawableState();
		mDownloadLayout.refreshDrawableState();
		mMapLayout.refreshDrawableState();
	}
	
	
	// Callback methods for media player
	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		Log.e(getClass().getName(), "DawinAdPlayer video player error.. finish dawin ad player");
		BKLog.e("what : " + what + ", extra : " + extra);
		
		if(mMediaPlayer != null && mMediaPlayer.isPlaying()) {
			mMediaPlayer.pause();
		}
		destroy();
		if(mPlayFinishListener != null) {
			mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
		}
		return false;
	}

	@Override
	public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
		BKLog.e("onVideoSizeChanged");
	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		mp.pause();
		mp.stop();
		mp.release();
		mIsPlayerInitialized = false;
		showProgress();
		// 과금테그 전송여부 확인
		if(mIsChargeTagSendSucceed) {
			if(mAdInfos != null) {
				mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
			} else {
				hideProgress();
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
				}
			}
		} else {
			if(mIsQuarterMinAd) {
				if(mAdInfos != null) {
					mConnectionManager.sendRequest(REQUEST_CHARGE, mAdInfos.getChargeTag(), null);
				} else {
					hideProgress();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
					}
				}
			} else {
				if(mAdInfos != null) {
					mConnectionManager.sendRequest(REQUEST_FINISHED, mAdInfos.getEndTag(), null);
				} else {
					hideProgress();
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_ACTION_COMPLETE);
					}
				}
			}
		}
		
	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		if(mAdInfos == null) {
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(this, AD_FINISH_OTHER_ERROR);
			}
			return;
		}
		try {
			BKLog.i("OnPrePaReD");
			showProgress();
			if(!mIsPlayerInitialized) {
				initializeVideoView();
			}
			if(mp != null) {// 20141222 몽키 테스트에서 해당 부분 null pointer exception 떨어져서 처리구문 추가함.(20141216 공통 라이브러리 수정본 적용)
				setVideoSize(mp.getVideoWidth(), mp.getVideoHeight());
				if(mVideoInfoListener != null) {
					mVideoInfoListener.onVideoInfoReceived(mp.getVideoWidth(), mp.getVideoHeight(), mp.getDuration());
				}
				BKLog.d("media width : " + mp.getVideoWidth() + ", media height : " + mp.getVideoHeight());
				BKLog.d("greatest common measure : " + CommonUtils.getGreatestCommonMeasure(mp.getVideoWidth(), mp.getVideoHeight()));
				
				int duration = mp.getDuration();
				
				if(duration < 16000) {
					// duration is under 16000msec -> it judges 15sec ad
					BKLog.e("============================== 15sec ad ================================");
					mIsQuarterMinAd = true;
				} else {
					BKLog.e("============================== other sec ad ================================");
					mIsQuarterMinAd = false;
				}
				
				try {
					if(mAdInfos != null) {
						if(mAdInfos.getChargeTime() > duration) {
							mChargeTime = duration - 500;
						} else {
							mChargeTime = mAdInfos.getChargeTime();
						}
						BKLog.e("Duration : " + duration + ", chargetime : " + mChargeTime + "real chargetime : " + mAdInfos.getChargeTime());
					}
				} catch(NumberFormatException e) {
					mChargeTime = mAdInfos.getChargeTime() - 1000;
				}
				
				if(mAdInfos != null) {
					BKLog.i("------------- Start new video");
					mLastSendedTag = 0;
					mAdDuration = mp.getDuration();
					mQuarter = mAdInfos.getQuarterTime(1);
					mQuarter2 = mAdInfos.getQuarterTime(2);
					mQuarter3 = mAdInfos.getQuarterTime(3);
					mHandler.sendEmptyMessage(MESSAGE_ADJUST_SURFACEVIEW);
					mp.start();
					startTimer();
					BKLog.e("Duration : " + mp.getDuration());
				} else {
					if(mIsTimerRunning) {
						if(mTimer != null) {
							cancelTimer();
						}
					}
					
					if(mPlayFinishListener != null) {
						mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_ERROR);
					}
				}
				
				if(mPreparedListener != null) {
					mPreparedListener.onPrepared();
				}
				
				// ticker timer init
				if(mTickerTimer == null) {
					mTickerTimer = new Timer();
				} else { 
					mTickerTimer.cancel();
					mTickerTimer.purge();
					if(mTickerTimerTask != null) {
						mTickerTimerTask.cancel();
					}
				}
				
				if(mTickerTimerTask == null) {
					mTickerTimerTask = new TimerTask() {
						@Override
						public void run() {
							if(mMediaPlayer != null && mTickerTimeListener != null) {
								try {
									mTickerTimeListener.OnTime(mMediaPlayer.getCurrentPosition());
								} catch(Exception e) {
									mTickerTimeListener.OnTime(-1);
									cancelTickerTimer();
								}
								
							}
							
						}
					};
				}
			} else {
				if(mPlayFinishListener != null) {
					mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
				}
			}
			
		} catch(Exception e) { 
			// Exception occured
			// Prepare 도중 
			e.printStackTrace();
			if(mPlayFinishListener != null) {
				mPlayFinishListener.onPlayFinished(DawinAdPlayer.this, AD_FINISH_OTHER_REASON);
			}
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		BKLog.w("SurfaceChanged");
		mSurfaceHolder = holder;
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		mSurfaceHolder = holder;
		BKLog.w("SurfaceCreated");
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		BKLog.w("SurfaceDestroyed");
	}
	
	// Mediaplayer duration timer controlls here.
	private void startTimer() {
		BKLog.d("Start Timer ----");
		if(mTimer == null) {
			mTimer = new Timer();
		} else { 
			mTimer.cancel();
			mTimer.purge();
			if(mTimerTask != null) {
				mTimerTask.cancel();
			}
		}
		
		if(mTimerTask == null) {
			mTimerTask = new TimerTask() {
				@Override
				public void run() {
					if(mMediaPlayer != null && mTimeListener != null) {
						try {
							mTimeListener.OnTime(mMediaPlayer.getCurrentPosition());
						} catch(Exception e) {
							mTimeListener.OnTime(-1);
							cancelTimer();
						}
						
					}
					
				}
			};
		}
		
		if(!mIsTimerRunning && mTimer != null && mTimerTask != null) {
			mIsTimerRunning = true;
			mTimer.schedule(mTimerTask, 0, 100);
		}
	}
	
	private void cancelTimer() {
		if(mIsTimerRunning) {
			mIsTimerRunning = false;
			mTimer.cancel();
			mTimer.purge();
			mTimer = null;
			
			mTimerTask.cancel();
			mTimerTask = null;
		}
		
		cancelTickerTimer();
	}

	

}
